﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Threading;
using XFControls;

namespace FBEntities.FBObjects
{
    public class FBNotificationListObject : IFBObject
    {
        public string notification_id;
        public long sender_id;
        public long recipient_id;
        public long created_time;
        public long updated_time;
        public string title_html;
        public string title_text;
        public string body_html;
        public string body_text;
        public string href;
        public long app_id;
        public int is_unread;
        public int is_hidden;
        public string object_id;
        public string object_type;

        #region IFBObject Members

        public void Parse(JObject text)
        {
            FBParseUtilities.Parse(text, this);
        }

        #endregion
    }

    public class FBNotificationObject
    {
        public int UnreadMessages;
        public long MostRecentMessageId;

        public int UnreadPokes;
        public long MostRecentPokeId;

        public int UnreadShares;
        public long MostRecentShareId;

        public List<long> FriendRequests;
        public List<long> GroupRequests;
        public List<long> EventRequests;

        public FBNotificationObject(JObject obj)
        {
            FriendRequests = new List<long>();
            GroupRequests = new List<long>();
            EventRequests = new List<long>();

            var msg = obj["messages"] as JObject;
            var pokes = obj["pokes"] as JObject;
            var shares = obj["shares"] as JObject;

            if(msg == null || pokes == null || shares == null)
                return;

            var fReq = obj["friend_requests"] as JArray;
            var gReq = obj["group_invites"] as JArray;
            var eReq = obj["event_invites"] as JArray;

            if (msg["unread"] != null)
                UnreadMessages = (int)msg["unread"];
            if (msg["most_recent"] != null)
                MostRecentMessageId = (long)msg["most_recent"];

            if (pokes["unread"] != null)
                UnreadPokes = (int)pokes["unread"];
            if (pokes["most_recent"] != null)
                MostRecentPokeId = (long)pokes["most_recent"];

            if (shares["unread"] != null)
                UnreadShares = (int)shares["unread"];
            if (shares["most_recent"] != null)
                MostRecentShareId = (long)shares["most_recent"];

            foreach (long id in fReq)
                FriendRequests.Add(id);
            foreach (long id in gReq)
                GroupRequests.Add(id);
            foreach (long id in eReq)
                EventRequests.Add(id);
        }

        public override bool Equals(object obj)
        {
            if (obj is FBNotificationObject)
            {
                var temp = obj as FBNotificationObject;

                return UnreadMessages == temp.UnreadMessages &&
                    UnreadPokes == temp.UnreadPokes &&
                    UnreadShares == temp.UnreadShares &&
                    FriendRequests.Count == temp.FriendRequests.Count &&
                    GroupRequests.Count == temp.GroupRequests.Count &&
                    EventRequests.Count == temp.EventRequests.Count;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

    }

    public class FBNotifications : IUpdateable
    {
        public event EventHandler Updated;
        public event UpdateEventHandler ListUpdated;
        public event UpdateEventHandler NotificationUpdated;
        public bool Show { get; set; }

        private string getUrl = "https://api.facebook.com/method/notifications.get?format=JSON&";
        private string getListUrl = "https://api.facebook.com/method/notifications.getList?format=JSON&";
        private int time = 60000;
        private List<FBNotificationListObject> _list;
        private FBNotificationObject _notification;

        private System.Windows.Forms.Timer _timer;

        public FBNotifications()
        {
            getUrl += FBParseUtilities.authKey;
            getListUrl += FBParseUtilities.authKey;

            _list = new List<FBNotificationListObject>();

            WaitCallback cbNote = new WaitCallback(updateNotification);
            WaitCallback cbList = new WaitCallback(updateList);

            ThreadPool.QueueUserWorkItem(cbNote);
            ThreadPool.QueueUserWorkItem(cbList);
        }

        public List<FBNotificationListObject> GetNotificationList()
        {
            return _list;
        }

        public FBNotificationObject GetNotifictaions()
        {
            return _notification;
        }

        public void StartUpdates()
        {
            if (_timer != null)
                _timer.Dispose();

            _timer = new System.Windows.Forms.Timer();
            _timer.Interval = time;
            _timer.Tick += (o, e) =>
            {
                WaitCallback cbNote = new WaitCallback(updateNotification);
                WaitCallback cbList = new WaitCallback(updateList);

                ThreadPool.QueueUserWorkItem(cbNote);
                ThreadPool.QueueUserWorkItem(cbList);
            };
        }

        public int GetNumber()
        {
            return _list.Count;
        }

        private void updateList(object val)
        {
            string json = FBCache.GetJSON("updatelist", getListUrl, false);

            if (!string.IsNullOrEmpty(json))
            {
                JObject o = JObject.Parse(json);

                var array = o["notifications"] as JArray;
                List<FBNotificationListObject> temp = new List<FBNotificationListObject>();

                for (int i = 0; i < array.Count; i++)
                {
                    if (array[i].Type == JTokenType.Null)
                        continue;

                    var itm = new FBNotificationListObject();
                    itm.Parse(array[i] as JObject);
                    temp.Add(itm);
                }

                if (_list.Count != temp.Count)
                {
                    _list = temp;
                    Show = true;
                    if (ListUpdated != null)
                        ListUpdated(this, new EventArgs());

                    if (Updated != null)
                        Updated(this, new EventArgs());
                }
            }
        }

        private void updateNotification(object val)
        {
            string json = FBCache.GetJSON("update", getUrl, false);

            if (!string.IsNullOrEmpty(json))
            {
                JObject o = JObject.Parse(json);
                var temp = new FBNotificationObject(o);

                if (_notification == null || !_notification.Equals(temp))
                {
                    _notification = temp;
                    if (NotificationUpdated != null)
                        NotificationUpdated(this, new EventArgs());

                    if (Updated != null)
                        Updated(this, new EventArgs());
                }
            }
        }
    }
}
/*
 List object:
 * 
 *{
    "notifications": [
    {
      "notification_id": "########",
      "sender_id": ########,
      "recipient_id": ########,
      "created_time": ########,
      "updated_time": ########,
      "title_html": "Html",
      "title_text": "Not Html",
      "body_html": "Html",
      "body_text": "Not Html",
      "href": "http://www.facebook.com/stuff",
      "app_id": ########,
      "is_unread": 0,
      "is_hidden": 0,
      "object_id": "########_########",
      "object_type": "stream"
    },

 * 
 Get Object:
 * 
 * {
  "messages": {
    "unread": 0,
    "most_recent": ########
  },
  "pokes": {
    "unread": 1,
    "most_recent": ########
  },
  "shares": {
    "unread": 0,
    "most_recent": 0
  },
  "friend_requests": [],
  "group_invites": [
    ########,
    ########,
    ########,
    ########,
    ########
  ],
  "event_invites": [
    ########,
    ########,
    ########,
    ########
  ]
}
 
 
 */